package chalmers.game.subterranean.model.world;


import chalmers.game.subterranean.model.world.squares.ISquare;
import chalmers.game.subterranean.model.world.squares.Square;
import chalmers.game.subterranean.model.world.squares.blocks.digblocks.Dirt;
import chalmers.game.subterranean.model.world.squares.blocks.resourceblocks.Coal;
import chalmers.game.subterranean.model.world.squares.blocks.resourceblocks.Diamond;
import chalmers.game.subterranean.model.world.squares.blocks.resourceblocks.Iron;
import chalmers.game.subterranean.util.BlockType;
import chalmers.game.subterranean.util.options.WorldValues;

import java.util.ArrayList;
import java.util.Random;

/**
 * @author Mikael Friederici
 */
public class DirtLevel extends DepthLevel {
  private ArrayList<BlockType.Resource> resourcePool;
  private BlockType.Resource resource;
  private int numbResourceBlocks;
  private int numbExtraResourceBlocks;

  public DirtLevel(GameWorld world, BlockType.Resource resource,
      ArrayList<BlockType.Resource> resourcePool) {
    super(world);
    this.resource = resource;
    this.resourcePool = resourcePool;
    generate();
  }

  public DirtLevel(GameWorld world) {
    super(world);
  }

  @Override
  public void generate() {
    int amountResource =
        randInt(WorldValues.LEVEL_MIN_NUM_RESOURCES, WorldValues.LEVEL_MAX_NUM_RESOURCES);
    int amountOtherResources =
        randInt(WorldValues.LEVEL_MIN_NUM_RESOURCES, WorldValues.LEVEL_MAX_NUM_RESOURCES);
    generateBlocks();
    generateResources(amountResource);
    generateOtherResources(amountOtherResources);
  }

  private void generateBlocks() {
    for (int i = 0; i < allSquares.length; i++) {
      for (int i1 = 0; i1 < allSquares[i].length; i1++) {
        if (Math.random() * 10 >= 5) {
          allSquares[i][i1] = new Square(new Dirt()); // This will create Dirt
        } else {
          allSquares[i][i1] = new Square(null); // This will create Air
        }
      }
    }
  }

  private void generateResources(int amount) {
    Random rand = new Random();
    for (int i = 0; i < allSquares.length; i++) {
      for (int i1 = 0; i1 < allSquares[i].length; i1++) {
        // 5% chance for the block to become resource block.
        if (rand.nextInt(20) == 1 && amount > 0) {
          Square s = blockFactory(resource);
          if(s != null)
            allSquares[i][i1] = s;
          amount--;
        }
      }
    }
    if (amount > 0) // run until all resources have been added to the level.
      generateResources(amount);
  }

  private void generateOtherResources(int amount) {
    if (resourcePool.size() == 0)
      return;
    Random rand = new Random();
    for (int i = 0; i < allSquares.length; i++) {
      for (int i1 = 0; i1 < allSquares[i].length; i1++) {
        // 5% chance for the block to become resource block.
        if (rand.nextInt(20) == 1 && amount > 0) {
          BlockType.Resource other = resourcePool.get(randInt(0, resourcePool.size() - 1));
          Square s = blockFactory(other);
          if(s != null)
            allSquares[i][i1] = s;
          amount--;
        }
      }
    }
    if (amount > 0) // run until all resources have been added to the level.
      generateResources(amount);
  }

  private Square blockFactory(BlockType.Resource type){
    switch(type){
      case COAL:
        return new Square(new Coal());
      case DIAMOND:
        return new Square(new Diamond());
      case IRON:
        return new Square(new Iron());
      default:
        return null;
    }
  }

  private static int randInt(int min, int max) {
    Random rand = new Random();
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
  }

  @Override
  ISquare[][] getBlocks() {
    return this.allSquares;
  }
}
